package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.model.ModelClosePriceMA5GoldCross;
import cn.com.acca.ma.pojo.SuccessRateOrPercentagePojo;
import cn.com.acca.ma.service.ModelClosePriceMA5GoldCrossService;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class ModelClosePriceMA5GoldCrossServiceImpl extends BaseServiceImpl<ModelClosePriceMA5GoldCrossServiceImpl, ModelClosePriceMA5GoldCross> implements
        ModelClosePriceMA5GoldCrossService {

    /*********************************************************************************************************************
     *
     * 												计算全部数据
     *
     *********************************************************************************************************************/
    /**
     * 海量地向表MDL_CLOSE_PRICE_MA5_GOLD_CROSS中插入数据
     */
    @Override
    public void writeModelClosePriceMA5GoldCross() {
        modelClosePriceMA5GoldCrossDao.writeModelClosePriceMA5GoldCross();
    }

    /**
     * 增量地向表MDL_CLOSE_PRICE_MA5_GOLD_CROSS中插入数据
     */
    @Override
    public void writeModelClosePriceMA5GoldCrossIncr() {
        String endDate = PropertiesUtil
                .getValue(MODEL_CLOSE_PRICE_MA5_GOLD_CROSS_PROPERTIES, "close.price.ma5.gold.cross.end_date");
        modelClosePriceMA5GoldCrossDao.writeModelClosePriceMA5GoldCrossIncr(endDate);
    }

    /*********************************************************************************************************************
     *
     * 												创建图片
     *
     *********************************************************************************************************************/
    /**
     * 创建close_price金叉ma5的成功率图
     */
    @Override
    public void createClosePriceMa5GoldCrossSuccessRatePicture(boolean multithreading) {
        logger.info("创建close_price金叉ma5的成功率图");

        String beginDate = PropertiesUtil
                .getValue(MODEL_CLOSE_PRICE_MA5_GOLD_CROSS_PICTURE_PROPERTIES, "close.price.ma5.gold.cross.success.rate.beginDate");
        String endDate = PropertiesUtil
                .getValue(MODEL_CLOSE_PRICE_MA5_GOLD_CROSS_PICTURE_PROPERTIES, "close.price.ma5.gold.cross.success.rate.endDate");
        Integer dateNumber = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_CLOSE_PRICE_MA5_GOLD_CROSS_PICTURE_PROPERTIES, "close.price.ma5.gold.cross.success.rate.dateNumber"));

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("All Stock Close", org.jfree.data.time.Day.class);
        TimeSeries closePriceMa5GoldCrossSuccessRateSeries = new TimeSeries("close_price ma5 gold cross Success Rate", org.jfree.data.time.Day.class);

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> closePriceMa5GoldCrossSuccessRateList = modelClosePriceMA5GoldCrossDao.getClosePriceMa5GoldCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);

        // 获取某一段时间内平均价格中的最大价格和最小价格，以便下面的归一化
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double averageCloseMaxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double averageCloseMinClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.add(new Day(day, month, year), this.averageCloseAfterAdjust(value, averageCloseMaxClose, averageCloseMinClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        // 获取某一段时间内成功率中的最大成功率和最小成功率，以便下面的归一化
        SuccessRateOrPercentagePojo successRateOrPercentagePojo = closePriceMa5GoldCrossSuccessRateList.get(0);
        double closePriceMa5GoldCrossSuccessRateMaxClose = (successRateOrPercentagePojo.getSuccessRateOrPercentage()).doubleValue();
        double closePriceMa5GoldCrossSuccessRateMinClose = (successRateOrPercentagePojo.getSuccessRateOrPercentage()).doubleValue();
        for (int i = 1; i < closePriceMa5GoldCrossSuccessRateList.size(); i++) {
            SuccessRateOrPercentagePojo theSuccessRateOrPercentagePojo = closePriceMa5GoldCrossSuccessRateList.get(i);
            Double value = theSuccessRateOrPercentagePojo.getSuccessRateOrPercentage().doubleValue();
            if (closePriceMa5GoldCrossSuccessRateMaxClose < value) {
                closePriceMa5GoldCrossSuccessRateMaxClose = value;
            }
            if (closePriceMa5GoldCrossSuccessRateMinClose > value) {
                closePriceMa5GoldCrossSuccessRateMinClose = value;
            }
        }

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < closePriceMa5GoldCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date closePriceMa5GoldCrossSuccessRateListDate = closePriceMa5GoldCrossSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(closePriceMa5GoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(closePriceMa5GoldCrossSuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                closePriceMa5GoldCrossSuccessRateSeries.add(new Day(day, month, year), this.averageCloseAfterAdjust(value, closePriceMa5GoldCrossSuccessRateMaxClose, closePriceMa5GoldCrossSuccessRateMinClose));
                i++;
                j++;
            } else if (averageAllCloseListDate.before(closePriceMa5GoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceMa5GoldCrossSuccessRateSeries.add(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceMa5GoldCrossSuccessRateSeries.add(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(closePriceMa5GoldCrossSuccessRateSeries);

        JFreeChart jfreechart;
        jfreechart = ChartFactory.createTimeSeriesChart("Close Price Ma5 Gold Cross Success Rate",
                "Close Price Ma5 Gold Cross Success Rate", "Close Price Ma5 Gold Cross Success Rate", timeSeriesCollection, true, true, true);
        jfreechart.setBackgroundPaint(Color.white);
        XYPlot xyplot = (XYPlot) jfreechart.getPlot();
        xyplot.setBackgroundPaint(Color.lightGray);
        xyplot.setDomainGridlinePaint(Color.white);
        xyplot.setRangeGridlinePaint(Color.white);
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyplot.setDomainCrosshairVisible(true);
        xyplot.setRangeCrosshairVisible(true);
        org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = xyplot.getRenderer();
        if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "close_price_ma5_gold_cross_success_rate/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String listToString(List list) {
        return null;
    }
}
